package service

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/go-kratos/kratos/v2/transport/http"
	"io"
	"os"
	algoV1 "stwin.net/api/ss-algorithm-robot/algoRobotV1"
	v1 "stwin.net/api/st-demo/demoV1"
	"stwin.net/zoro/zresp"
	"stwin.net/zoro/zrpc"
	"stwin.net/zoro/ztool"
	"time"
)

func (s *DemoService) UploadFile(ctx http.Context) (err error) {
	traceId := ztool.ZStr.GetUUIDPureStr()
	file, header, err := ctx.Request().FormFile("file")
	if err != nil {
		return
	}
	defer file.Close()

	// 修改文件名并创建保存
	oriFile, err := os.Create("./files/" + header.Filename)
	if err != nil {
		return
	}
	defer oriFile.Close()

	// 将文件内容复制到保存的文件中
	_, err = io.Copy(oriFile, file)
	if err != nil {
		return
	}
	s.log.WithContext(ctx).Infof("上传文件 %v 到服务器,traceId = %v", header.Filename, traceId)
	bytes, _ := json.Marshal(&zresp.HttpResponse{
		Code:    200,
		Msg:     "upload done",
		Data:    nil,
		TraceId: traceId, // 这种方式是获取不到 traceId 的，需要自己单独给一个
	})

	_, err = ctx.Response().Write(bytes)
	return nil
}

func (s *DemoService) Download(ctx http.Context) error {
	imageFile, err := os.Open("./files/gogogo.apk")
	if err != nil {
		return err
	}
	defer imageFile.Close()
	payload, err := io.ReadAll(imageFile)
	if err != nil {
		return err
	}
	// 设置HTTP响应头
	// 打开为预览
	//ctx.Response().Header().Set("Content-Type", "image/png")
	// 打开为下载
	ctx.Response().Header().Set("Content-Type", "application/octet-stream")
	fileName := "gogogo.apk"
	ctx.Response().Header().Set("Content-Disposition", fmt.Sprintf("%v%v", "attachment; filename=", fileName))
	// 将结果写入
	_, err = ctx.Response().Write(payload)
	return err
}

func (s *DemoService) TimeoutTest(ctx context.Context, req *v1.TimeoutTestReq) (*v1.TimeoutTestResp, error) {
	for i := 0; i < 20; i++ {
		time.Sleep(1 * time.Second)
		if deadline, ok := ctx.Deadline(); ok {
			if deadline.Unix() <= time.Now().Unix() {
				// 服务已经超时
				s.log.WithContext(ctx).Infof("服务已经超时,可以手动决定是否提前终止")
			} else {
				s.log.WithContext(ctx).Infof("服务还没超时 deadline = %v，现在时间为 %v deadlineUnix = %v，现在时间Unix为 %v", deadline, time.Now(), deadline.Unix(), time.Now().Unix())
			}
		}
	}

	s.log.WithContext(ctx).Infof("10s 未超时，打印的结果")
	return nil, nil
}

func (s *DemoService) AddDemoData(ctx context.Context, req *v1.AddDemoDataReq) (*v1.AddDemoDataResp, error) {
	// 获取客户端ip
	clientIp := ztool.ZZoro.GetClientIp(ctx)
	s.log.WithContext(ctx).Infof("客户端ip = %v", clientIp)
	time.Sleep(1 * time.Second)
	return s.uc.AddDemoData(ctx, req.Age, req.Name)
}

// 调用 rpc 的案例
func (s *DemoService) AddDemoData2(ctx context.Context, req *v1.AddDemoData2Req) (*v1.AddDemoData2Resp, error) {
	client, err := zrpc.GetRpc().GetStAlgoRobot(ctx)
	if err != nil {
		s.log.WithContext(ctx).Errorf("grpc fail = %v", err)
		return nil, err
	}
	resp, err := client.GetRobotId(ctx, &algoV1.GetRobotIdReq{
		RobotId: "",
		ProdId:  1,
		MatchId: "111",
		Uid:     123456,
	})
	s.log.WithContext(ctx).Infof("alogo grpc rssp = %v", resp)

	return s.uc.AddDemoData2(ctx, req.Age, req.Name)
}
